Bean的生命周期:创建 -> 初始化 -> 销毁 的过程。Bean的生命周期由Spring 容器管理 。我们可以自定义Bean的初始化和销毁方法,容器在Bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法。
Bean创建:Bean创建的时候,单实例Bean是在容器启动的时候创建,多实例Bean是在每次获取的时候创建对象。
Bean初始化:对象创建完成,并赋值好后,调用初始化方法。
Bean销毁:单实例Bean是在Spring容器关闭的时候调用销毁的方法。多实例Bean,Spring容器是不会调用销毁方法。我们可以手动调用销毁方法。
由五种定义初始化和销毁方法的方式:
方式一:在使用xml配置方式的时候,我们可以在
<bean>标签中指定init-method和destroy-method两个属性来指定初始化和销毁方法,初始化和销毁方法不能有参数,但可以抛出异常。方式二:使用
@Bean指定初始化和销毁方法。方式三:让Bean实现
InitializingBean和DisposableBean接口方式四:使用JSR250规范里的
@PostConstruct和@PreDestroy注解。方式五:使用Bean的后置处理器
BeanPostProcessor。后置处理器的作用:在Bean初始化前后进行一些处理操作。
1 @Bean指定初始化和销毁方法
@Bean注解由两个属性:initMethod和destroyMethod。通过这两个方法来指定初始化和销毁方法。
一、有一个Bean如下:
1  | public class Car {  | 
二、配置类如下,在配置类中我们注入了Car这个Bean,并使用@Bean注解指定了这个Bean的初始化和销毁方法。
1  | 
  | 
2 Bean实现InitializingBean和DisposableBean接口
 让Bean实现InitializingBean接口,并重写初始化方法afterPropertiesSet。该方法会在Bean创建完成,并属性都赋值完成后调用。
让Bean实现DisposableBean接口,并重写销毁方法destroy。单实例Bean,该方法在容器关闭的时候调用。
示例:
1  | 
  | 
配置类中使用包扫描注入该Bean。
3 使用@PostConstruct和@PreDestroy注解
@PostConstruct:在Bean创建完成,并且属性赋值完成后,来执行初始化方法。
@PreDestroy:在容器销毁Bean之前,来执行销毁方法。
注意:@PostConstruct和@PreDestroy都是只能标注在方法上的注解。
示例:
1  | 
  | 
配置类中使用包扫描注入该Bean。
4、使用后置处理器BeanPostProcessor
4.1 BeanPostProcessor的示例
后置处理器BeanPostProcessor是一个接口,它有两个方法:postProcessBeforeInitialization和postProcessAfterInitialization。
postProcessBeforeInitialization:在创建Bean实例,对Bean的属性赋值,并在任何初始化方法调用之前执行,例如实现InitializingBean接口的afterPropertiesSet方法,或者是自定义的init-method方法。1
2> 原文:Apply this BeanPostProcessor to the given new bean instance <i>before</i> any bean initialization callbacks (like InitializingBean's {@code afterPropertiesSet} or a custom init-method).
>postProcessAfterInitialization:在初始化方法调用之后执行。1
2> 原文:Apply this BeanPostProcessor to the given new bean instance <i>after</i> any bean initialization callbacks (like InitializingBean's {@code afterPropertiesSet} or a custom init-method).
>
一、定义自己的后置处理器
1  | 
  | 
执行顺序:构造方法 -> 后置处理器的前置处理 -> afterPropertiesSet/@PostConstruct -> 后置处理器的后置处理。
简而言之,在 初始化方法执行之前执行
postProcessBeforeInitialization,在初始化方法执行之后执行postProcessAfterInitialization。若没有自定义初始化方法,后置处理器也是会执行的。
4.2 BeanPostProcessor的原理
通过查看Spring源码,AbstractAutowireCapableBeanFactory类中有一个initializeBean方法,该方法中调用了invokeInitMethods方法,用来执行初始化方法(afterPropertiesSet或自定义初始化方法)。在调用了invokeInitMethods方法前调用了applyBeanPostProcessorsBeforeInitialization方法,在调用了invokeInitMethods方法后调用了applyBeanPostProcessorsAfterInitialization方法。
源码:
1  | protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {  | 
在执行
initializeBean之前执行了populateBean方法,对bean属性进行赋值。
4.3 BeanPostProcessor在Spring底层的使用
以几个BeanPostProcessor的实现类为例:
4.3.1 ApplicationContextAwareProcessor
一、【作用】:是可以向组件中注入IOC容器。
二、【使用】:
例如有一个组件Pig,实现ApplicationContextAware接口,重写接口中的setApplicationContext方法。
1  | public class Pig implements ApplicationContextAware {  | 
这样就把容器注入到组件中了。
三、【原理】:
通过查看ApplicationContextAwareProcessor中的postProcessBeforeInitialization方法:
1  | class ApplicationContextAwareProcessor implements BeanPostProcessor {  | 
以我们这个为例,在bean执行初始化之前,先判断这个bean是否实现了
ApplicationContextAware,如果是,则调用invokeAwareInterfaces,向bean中注入值。如果是
ApplicationContextAware,就将applicationContext注入。
4.3.2 InitDestroyAnnotationBeanPostProcessor
一、【作用】:用来处理@PostConstruct和@PreDestroy注解的。这就是为什么标注了这两个注解的方法称为生命周期方法的原因。
二、【原理】:
1  | public class InitDestroyAnnotationBeanPostProcessor  | 
4.3.3 AutowiredAnnotationBeanPostProcessor
【作用】:用来处理@Autowired注解,这就是为什么标注的@AutoWired注解的属性可以进行依赖注入的原因。